;------------------------------------------
;s15.asm
;在DOS下，按下“A”键后，除非不在松开，如果松开“A”后，除非不在松开，如果松开，就显示满屏的的“A”
;-----------------------------------------
assume cs:code
stack segment
    db 128 dup(0)
stack ends 


code segment
    start:
        
        push cs
        pop ds ;设置ds为cs地址

        mov ax,0
        mov es,ax ;目标段地址

        mov si,offset int9  ;设置ds:si指向源地址
        mov di,204h         ;设置es:di指向目的地址
        mov cx,offset int9end - offset int9 ;设置cx为传输长度
        cld
        rep movsb

        push es:[9*4]  ;将向量表中9号ip压栈
        pop es:[200h]  ;弹栈到0:200H处
        push es:[9*4+2] ;将向量表中9号cs压栈
        pop es:[202h] ; 将原来的入口地址保存在es:[200h] ，es:[202h] 地址

        cli  ;IF置0的原因就是，在进入中断处理程序后，禁止其他的可屏蔽中断。
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0
        sti

        mov ax,4c00h
        int 21h
        
    int9:
        push ax
        push bx
        push cx
        push es

        in al,60h ;从端口60h读取数据
        ;模拟的是int 9 指令
        pushf ;pushf的功能是将标志寄存器的值压栈，
        call dword ptr cs:[200h];此中断例程执行是 (cs)=0 

        cmp al,9Eh;判断是不是断码a
        jne int9ret

        mov ax, 0b800h
        mov es, ax      
        mov bx,0      ;修改字符，修改高位
        mov cx,2000
    s:
        mov byte ptr es:[bx],'A'
        add bx,2
        loop s

    int9ret: 
        pop es
        pop cx
        pop bx
        pop ax

        iret 
    int9end: nop

code ends
end start    

